package main

import (
	"os/exec"
	"strings"

	_ "github.com/ying32/govcl/pkgs/winappres"
	"github.com/ying32/govcl/vcl"
	"github.com/ying32/govcl/vcl/types"
)

type MainForm struct {
	*vcl.TForm
	menu         *vcl.TMainMenu
	consoleForm  *vcl.TForm
	consoleLog   *vcl.TMemo
	fixComboBox  *vcl.TComboBox
	sidebar      *vcl.TListBox
	contentFrame [5]*vcl.TFrame
	currentIndex int

	coderFrame
	documentFrame
	developFrame
	testCaseFrame
}

type coderFrame struct {
	dbList      *vcl.TComboBox
	tables      *vcl.TLabeledEdit
	basePath    *vcl.TLabeledEdit
	mode        *vcl.TComboBox
	basePackage *vcl.TLabeledEdit
	exec        *vcl.TButton
	openDir     *vcl.TButton
}

type documentFrame struct {
	dbList   *vcl.TComboBox
	tables   *vcl.TLabeledEdit
	filePath *vcl.TLabeledEdit
	mode     *vcl.TComboBox
}

type developFrame struct {
	jsonViewer       *vcl.TButton
	codeConversion   *vcl.TButton
	formatConversion *vcl.TButton
}

type testCaseFrame struct {
	filePath *vcl.TLabeledEdit
}

var mainForm *MainForm

func initView() {
	vcl.RunApp(&mainForm)
}

func (f *MainForm) OnFormCreate(_ vcl.IObject) {
	f.openJsonViewer(true)
	f.SetCaption("开发工具箱")
	f.SetPosition(types.PoScreenCenter)
	f.SetWidth(width)
	f.SetHeight(height)
	f.SetBorderStyle(types.BsSingle)
	f.SetOnShow(func(sender vcl.IObject) {
		go f.setSidebarData()
	})

	f.fixComboBox = vcl.NewComboBox(f)
	f.fixComboBox.SetParent(f)
	f.fixComboBox.SetBounds(empty, empty, empty, empty)
	f.fixComboBox.SetStyle(types.CsDropDownList)

	f.initMenu()
	f.initSidebar()

	f.createConsoleForm()

	// 检查更新
	go f.CheckUpdate()
}

// 设置菜单
func (f *MainForm) initMenu() {
	f.menu = vcl.NewMainMenu(f)

	// 数据源
	item := vcl.NewMenuItem(f)
	item.SetCaption("数据源(&D)")

	subMenu := vcl.NewMenuItem(f)
	subMenu.SetCaption("管理(&N)")
	subMenu.SetOnClick(func(vcl.IObject) {
		f.dbManage()
	})
	item.Add(subMenu)

	subMenu = vcl.NewMenuItem(f)
	subMenu.SetCaption("-")
	item.Add(subMenu)

	subMenu = vcl.NewMenuItem(f)
	subMenu.SetCaption("退出(&Q)")
	subMenu.SetOnClick(func(vcl.IObject) {
		f.Close()
	})
	item.Add(subMenu)
	f.menu.Items().Add(item)

	// 配置
	item = vcl.NewMenuItem(f)
	item.SetCaption("配置(&C)")

	subMenu = vcl.NewMenuItem(f)
	subMenu.SetCaption("加载配置(&L)")
	item.Add(subMenu)
	f.menu.Items().Add(item)

	// 关于
	item = vcl.NewMenuItem(f)
	item.SetCaption("关于(&A)")

	subMenu = vcl.NewMenuItem(f)
	subMenu.SetCaption("帮助(&H)")
	item.Add(subMenu)
	f.menu.Items().Add(item)

	// 右键菜单
	pm := vcl.NewPopupMenu(f)
	item = vcl.NewMenuItem(f)
	item.SetCaption("数据源管理(&D)")
	item.SetOnClick(func(vcl.IObject) {
		f.dbManage()
	})
	pm.Items().Add(item)

	item = vcl.NewMenuItem(f)
	item.SetCaption("退出(&E)")
	item.SetOnClick(func(vcl.IObject) {
		f.Close()
	})
	pm.Items().Add(item)
	f.SetPopupMenu(pm)
}

func (f *MainForm) addUpdateMenu(url string) {
	item := vcl.NewMenuItem(f)
	item.SetCaption("下载新版本(&U)")
	item.SetOnClick(func(sender vcl.IObject) {
		_ = exec.Command(`cmd`, `/c`, `start`, url).Start()
	})
	f.menu.Items().Add(item)
}

// 菜单列表
func (f *MainForm) initSidebar() {
	f.sidebar = vcl.NewListBox(f)
	f.sidebar.SetParent(f)
	f.sidebar.SetStyle(types.LbOwnerDrawFixed)
	f.sidebar.SetBorderStyle(types.BsNone)
	f.sidebar.SetAlign(types.AlLeft)
	f.sidebar.SetWidth(sidebarWidth)
	f.sidebar.SetColor(sidebarColor)
	f.sidebar.SetItemHeight(sidebarItemHeight)
	f.sidebar.SetOnClick(func(sender vcl.IObject) {
		f.showFrame(int(f.sidebar.ItemIndex()))
	})
	f.sidebar.SetOnDrawItem(func(control vcl.IWinControl, index int32, aRect types.TRect, state types.TOwnerDrawState) {
		canvas := f.sidebar.Canvas()
		menuItemText := f.sidebar.Items().Strings(index)
		textHeight := canvas.TextHeight(menuItemText)
		canvas.Font().SetColor(sidebarFontColor)
		canvas.FillRect(aRect)
		canvas.Pen().SetColor(sidebarColor)
		canvas.Rectangle(aRect.Left, aRect.Top, aRect.Right, aRect.Bottom)
		if state.In(types.OdSelected) {
			canvas.Brush().SetColor(sidebarSelectedColor)
			canvas.Rectangle(aRect.Left, aRect.Top, aRect.Right, aRect.Bottom)
			canvas.Font().SetColor(sidebarFontColor)
			if state.In(types.OdFocused) {
				canvas.DrawFocusRect(aRect)
			}
		}
		canvas.TextOut(sidebarItemLeft, aRect.Top+(sidebarItemHeight-textHeight)/2, menuItemText)
	})

	// 绘制主页面方法
	createFrameMap := map[int]interface{}{
		0: f.createCoderFrame,
		1: f.createDocumentFrame,
		2: f.createDevelopFrame,
		3: f.createTestCaseFrame,
		4: f.createOtherFrame,
	}

	// 循环绘制主页面和页面内结构
	for i := range sidebarList {
		createFrameMap[i].(func(int))(i)
	}
}

// 设置菜单列表
func (f *MainForm) setSidebarData() {
	for _, menu := range sidebarList {
		vcl.ThreadSync(func() {
			f.sidebar.Items().Add(menu)
		})
	}
	vcl.ThreadSync(func() {
		f.showFrame(defaultIndex)
		f.sidebar.SetSelected(defaultIndex, true)
	})
}

func (f *MainForm) createConsoleForm() {
	f.consoleForm = vcl.NewForm(f)
	f.consoleForm.SetPosition(types.PoMainFormCenter)
	f.consoleForm.SetWidth(width * 1.2)
	f.consoleForm.SetHeight(height * 1.2)

	f.consoleLog = vcl.NewMemo(f.consoleForm)
	f.consoleLog.SetParent(f.consoleForm)
	f.consoleLog.SetScrollBars(types.SsBoth)
	f.consoleLog.SetReadOnly(true)
	f.consoleLog.SetAlign(types.AlClient)

	f.consoleForm.SetOnShow(func(sender vcl.IObject) {
		f.consoleLog.Clear()
	})
	f.consoleForm.SetOnClose(func(sender vcl.IObject, action *types.TCloseAction) {
		f.BringToFront()
	})
}

// 显示主要内容
func (f *MainForm) showFrame(index int) {
	// 绘制主页面方法
	for i := 0; i < len(f.contentFrame); i++ {
		if index == i {
			f.currentIndex = index
			f.contentFrame[i].Show()
		} else {
			f.contentFrame[i].Hide()
		}
	}
}

// 选择数据表窗口
func (f *MainForm) selectTablesForm(dbIndex int32, callback func(tableStr string)) {
	table := vcl.NewForm(f)
	table.SetCaption("选择数据库表")
	table.SetPosition(types.PoMainFormCenter)
	table.SetBorderStyle(types.BsSingle)
	table.SetWidth(dbWidth)
	table.SetHeight(dbHeight)

	//  数据库表列表
	listBox := vcl.NewCheckListBox(table)
	listBox.SetParent(table)
	listBox.SetAlign(types.AlClient)
	go func() {
		if err, tables := loadTables(DBConfig{
			DBHost:     dbConfigs[dbIndex].DBHost,
			DBName:     dbConfigs[dbIndex].DBName,
			DBUsername: dbConfigs[dbIndex].DBUsername,
			DBPassword: dbConfigs[dbIndex].DBPassword,
		}); err != nil {
			vcl.ShowMessage("获取数据表信息失败" + lineBreak + err.Error())
			table.Close()
		} else {
			vcl.ThreadSync(func() {
				for i := 0; i < len(tables); i++ {
					listBox.Items().Add(tables[i].TableName)
				}
			})
		}
	}()

	all := vcl.NewButton(table)
	all.SetParent(table)
	all.SetCaption("全选")
	all.SetAlign(types.AlBottom)
	all.SetOnClick(func(sender vcl.IObject) {
		listBox.CheckAll(types.CbChecked, true, true)
	})

	none := vcl.NewButton(table)
	none.SetParent(table)
	none.SetCaption("取消全选")
	none.SetAlign(types.AlBottom)
	none.SetOnClick(func(sender vcl.IObject) {
		listBox.CheckAll(types.CbUnchecked, true, true)
	})

	confirm := vcl.NewButton(table)
	confirm.SetParent(table)
	confirm.SetCaption("确定")
	confirm.SetAlign(types.AlBottom)
	confirm.SetOnClick(func(sender vcl.IObject) {
		tableStr := ""
		tablesChk := strings.Split(listBox.Items().Text(), lineBreak)
		for i, tableName := range tablesChk {
			if len(tableName) > 0 && listBox.Checked(int32(i)) {
				tableStr += tableName + separator
			}
		}
		callback(tableStr)
		table.Close()
	})

	table.ShowModal()
}

func (f *MainForm) GetContentWidth(left int32) int32 {
	newWidth := f.Width() - sidebarWidth - commonPadding - left
	if newWidth > 0 {
		return newWidth
	} else {
		return empty
	}
}

func (f *MainForm) GetContentHeight(top int32) int32 {
	newHeight := f.Height() - top - commonPadding
	if newHeight > 0 {
		return newHeight
	} else {
		return empty
	}
}

func (f *MainForm) fixComboBoxErr() {
	f.fixComboBox.SetFocus()
}
